"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const cors_1 = __importDefault(require("cors"));
const pg_1 = require("pg");
const dotenv_1 = __importDefault(require("dotenv"));
// Load environment variables
dotenv_1.default.config();
const app = (0, express_1.default)();
const port = process.env.PORT || 8085;
// Middleware
app.use((0, cors_1.default)());
app.use(express_1.default.json());
// PostgreSQL connection
const pool = new pg_1.Pool({
    user: process.env.DB_USER || 'wuzhao',
    host: process.env.DB_HOST || 'localhost',
    database: process.env.DB_NAME || 'wuzhao',
    password: process.env.DB_PASSWORD || 'wuzhao2025',
    port: parseInt(process.env.DB_PORT || '15432'),
});
// Initialize database tables
function initDatabase() {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const client = yield pool.connect();
            // Create srs_callbacks table
            yield client.query(`
      CREATE TABLE IF NOT EXISTS srs_callbacks (
        id SERIAL PRIMARY KEY,
        action VARCHAR(50) NOT NULL,
        client_id VARCHAR(100),
        ip VARCHAR(45),
        vhost VARCHAR(100),
        app VARCHAR(100),
        stream VARCHAR(100),
        param TEXT,
        server_id VARCHAR(100),
        stream_url VARCHAR(255),
        stream_id VARCHAR(100),
        tc_url VARCHAR(255),
        page_url VARCHAR(255),
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      )
    `);
            // Create srs_heartbeats table
            yield client.query(`
      CREATE TABLE IF NOT EXISTS srs_heartbeats (
        id SERIAL PRIMARY KEY,
        device_id VARCHAR(100),
        ip VARCHAR(45),
        summaries JSONB,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      )
    `);
            client.release();
            console.log('Database tables initialized successfully');
        }
        catch (error) {
            console.error('Error initializing database:', error);
        }
    });
}
// Generic callback handler
function handleCallback(req, res, action) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const callbackData = req.body;
            console.log(`Received ${action} callback:`, callbackData);
            const client = yield pool.connect();
            const query = `
      INSERT INTO srs_callbacks 
      (action, client_id, ip, vhost, app, stream, param, server_id, stream_url, stream_id, tc_url, page_url)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
      RETURNING id
    `;
            const values = [
                action,
                callbackData.client_id,
                callbackData.ip,
                callbackData.vhost,
                callbackData.app,
                callbackData.stream,
                callbackData.param,
                callbackData.server_id,
                callbackData.stream_url,
                callbackData.stream_id,
                callbackData.tcUrl,
                callbackData.pageUrl
            ];
            const result = yield client.query(query, values);
            client.release();
            console.log(`Stored ${action} callback with ID:`, result.rows[0].id);
            // Return success response as required by SRS
            res.status(200).json({ code: 0, msg: 'OK' });
        }
        catch (error) {
            console.error(`Error handling ${action} callback:`, error);
            res.status(500).json({ code: 1, msg: 'Internal server error' });
        }
    });
}
// SRS Callback endpoints
app.post('/api/v1/streams', (req, res) => {
    const action = req.body.action;
    if (action === 'on_publish' || action === 'on_unpublish') {
        handleCallback(req, res, action);
    }
    else {
        res.status(400).json({ code: 1, msg: 'Invalid action' });
    }
});
app.post('/api/v1/sessions', (req, res) => {
    const action = req.body.action;
    if (action === 'on_play' || action === 'on_stop') {
        handleCallback(req, res, action);
    }
    else {
        res.status(400).json({ code: 1, msg: 'Invalid action' });
    }
});
app.post('/api/v1/dvrs', (req, res) => {
    handleCallback(req, res, 'on_dvr');
});
app.post('/api/v1/hls', (req, res) => {
    const action = req.body.action;
    if (action === 'on_hls' || action === 'on_hls_notify') {
        handleCallback(req, res, action);
    }
    else {
        res.status(400).json({ code: 1, msg: 'Invalid action' });
    }
});
// Heartbeat endpoint
app.post('/api/v1/servers', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const heartbeatData = req.body;
        console.log('Received heartbeat:', heartbeatData);
        const client = yield pool.connect();
        const query = `
      INSERT INTO srs_heartbeats 
      (device_id, ip, summaries)
      VALUES ($1, $2, $3)
      RETURNING id
    `;
        const values = [
            heartbeatData.device_id,
            heartbeatData.ip,
            heartbeatData.summaries ? JSON.stringify(heartbeatData.summaries) : null
        ];
        const result = yield client.query(query, values);
        client.release();
        console.log('Stored heartbeat with ID:', result.rows[0].id);
        res.status(200).json({ code: 0, msg: 'OK' });
    }
    catch (error) {
        console.error('Error handling heartbeat:', error);
        res.status(500).json({ code: 1, msg: 'Internal server error' });
    }
}));
// Health check endpoint
app.get('/health', (req, res) => {
    res.status(200).json({ status: 'OK', timestamp: new Date().toISOString() });
});
// Get callbacks endpoint (for debugging)
app.get('/api/v1/callbacks', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const client = yield pool.connect();
        const result = yield client.query('SELECT * FROM srs_callbacks ORDER BY created_at DESC LIMIT 100');
        client.release();
        res.json(result.rows);
    }
    catch (error) {
        console.error('Error fetching callbacks:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
}));
// Get heartbeats endpoint (for debugging)
app.get('/api/v1/heartbeats', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const client = yield pool.connect();
        const result = yield client.query('SELECT * FROM srs_heartbeats ORDER BY created_at DESC LIMIT 100');
        client.release();
        res.json(result.rows);
    }
    catch (error) {
        console.error('Error fetching heartbeats:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
}));
// Start server
function startServer() {
    return __awaiter(this, void 0, void 0, function* () {
        yield initDatabase();
        app.listen(port, () => {
            console.log(`SRS Callback API server listening at port: ${port}`);
            console.log(`Health check: http://localhost:${port}/health`);
            console.log(`Callbacks endpoint: http://localhost:${port}/api/v1/callbacks`);
            console.log(`Heartbeats endpoint: http://localhost:${port}/api/v1/heartbeats`);
        });
    });
}
startServer().catch(console.error);
